Rhapsody Developer Release Copyright 1997 by Apple
Computer, Inc. All Rights Reserved.
These notes are for the Rhapsody Developer Release of the compiler. This compiler is based on the GNU C compiler, version 2.7.2.1. It compiles programs written in C, C++, Objective-C, or Objective-C++.
The following new features have been added to the compiler since
the release of the OPENSTEP 4.2 compiler.
wchar_t
is now typedef
'd to a 32-bit
int
.
All compilers now understand the following pragmas:
#pragma options align=
word
#pragma pack(
n)
These pragmas affect how fields are aligned within structures.
Normally, fields are aligned on natural boundaries in such a way that
32-bit quantities are 4-byte aligned. However, when you use the
option align
or pack(2)
pragmas, fields
whose size is at least 16 bits are aligned on even addresses.
The cc command line flag -fpascal-strings enables
the compiler to permit Pascal strings to be recognized. A Pascal
string is a string containing an initial "\p". During compilation,
the string's initial "\p" will be replaced with a byte containing the
length of the string (not including the "\p"). The type of such a
string is unsigned
char *
. It is an error
for any pascal string to be longer than 255 characters. When a "\p"
is seen in a string and the -fpascal-strings flag is not
given, the compiler will issue a warning (just as older compilers do)
about an unknown escape sequence.
The Mac OS makes heavy use of file types and file creators (in a C
type called OSType
), written as character constants
containing four characters. The compiler will normally issue warnings
whenever it sees such a character constant. When the command -ine
flag -Wno-four-char-constants is given, the compiler will not
issue that warning.
Although they are not new, the following features are not documented elsewhere:
The C++ and Objective-C++ compilers no longer switch the list of
valid keywords when they see the extern "C"
construct.
This may cause existing C++ and Objective-C++ code to fail to
compile. The extern "Objective-C"
construct can still be
used, as in the past, to switch to a mode in which C++-specific
keywords such as "class" and "template" can be used as identifiers.
The header files have been sanitized and no longer use C++ keywords as parameter names, struct field names, or function names. (Rhapsody header files have undergone the same kind of scrutiny as OPENSTEP and PDO files.) The updated header files should make using C++ on Rhapsody easier (than on OPENSTEP) and more like other C++ development environments.
Before you re-compile C++ code with this new compiler, you might
have to rename certain constructs in your C header files or use
extern "Objective-C"
instead of extern "C"
.
In general, you should be able to include any Windows header file in an Objective-C source module without problems. The System framework contains Microsoft's header files, with slight modifications to make them compatible with gcc. For instance, slight changes have been made for unnamed unions, Microsoft assembly, and so on. If you have problems including any of the Windows header files, try including the file winnt-pdo.h before the Windows header file that's causing problems.
The -Wmost compiler flag is equivalent to the Free Software Foundation's -Wall, except that it doesn't turn on -Wparenthesis. The -Wmost flag also suppresses warning messages about inline functions and static constants that are not actually used. This flag is for internal use, and its definition may change in a future release.
You can now specify frameworks on the linker and preprocessor command lines. The -framework flag is accepted by both the linker and the preprocessor, while the -F flag is accepted by the linker only. These flags are defined as follows:
In your Objective-C code, include framework headers using the following format:
#include <
framework/include_file
.h>
Where framework is the name of the framework (such as AppKit or Foundation; don't include the extension) and include_file is the name of the header file to be included.
If the name of your source file ends in .cc, .cxx, .cpp, or .C, gcc attempts to compile your program with the C++ compiler. Similarly, if the name of your source file ends in .M, gcc attempts to compile your program with the Objective-C++ compiler. Although the Objective-C++ compiler does recognize the .mm extension, the Project Builder makefiles do not curently support compilation of files with that extension (see known bugs).
The compiler includes two new options to assist in debugging. Specify the -H flag on the command to have the compiler emit a listing of included header files (indented to reflect where they are included). Specify the -dM option after the -E (preprocess) option to get a listing of all macros along with their full definitions.
On Rhapsody, the compiler generates position-independent code by default. You can control the code generation style using the -dynamic and -static compiler flags; -dynamic specifies that position-independent code generation is to be used, whereas -static specifies position-dependent code generation.
If you are building drivers and kernel servers, be sure to include -static on the command line so that position-dependent code is generated. Compilation with the -dynamic option assumes that the dynamic link editor (/usr/lib/dyld) is available to the running program, and that is not the case for modules to be loaded into the kernel.
long long int
cause the
compiler to crash when optimization is turned on and the target is
PowerPC. The workaround is to compile with optimization turned
off.
Avoid using the -posix switch; there are no POSIX-specific libraries.
Although keyword-switching no longer occurs inside a context
tagged by the extern "C"
linkage directive, the C++
keywords are turned off inside an extern "Objective-C"
{...}
range. When entering and exiting this context, the
actual switch in keyword sets may occur a token or two late, meaning
that you may get syntax errors on legal code. For example, if the
first token following an extern "Objective-C"
range is
"class", this will be interpreted as an identifier and not the C++
class keyword. You can work around this by re-ordering your
declarations or inserting a dummy declaration after a
keyword-switching boundary.
(69211). Programs on Windows NT must add explicit references to at least one class in each framework in order to avoid link errors at run time. For instance, you could add a function like that in the following code excerpt, which refers to classes in each of Enterprise Objects Framework's layers. Though never invoked, it forces the appropriate linking to occur.
#ifdef WIN32 #import <EOControl/EOControl.h>#import <EOAccess/EOAccess.h>#import <EOInterface/EOInterface.h> void _referenceAllEOFrameworks() { [EODisplayGroup new]; // EOInterface [EOEntity new]; // EOAccess [EOEditingContext new]; // EOControl } #endif
If you create a project with the type "EOF Application," this code is automatically added to your project main file.
(63746). The precomp-related options are not yet supported on Windows NT.
Unless constant strings (both char *
and NSString)
are 7-bit, your code will not be portable because compilers deal with
8-bit strings in a machine-dependent encoding.
(66861). If you create an executable using the Windows NT compiler, and don't use the -o flag to explicitly tell gcc what to name it, gcc will most likely give it a random name.
(61306). The -pipe flag doesn't work in the Windows NT compiler.
(67853). On other platforms, when the compiler crashes (a rare event), it might generate some assembly language output before it goes down. If you use the -pipe flag, the assembler may not be able to detect the fact that its input is incomplete. As a result, the assembler may produce an incomplete, but valid .o file. If you use the make utility to build your application, make will detect the fact that there was a problem during compilation. However, when make is subsequently invoked, it might not recompile the source file that caused the problem, and the linker will probably complain about unresolved external symbols.
(69156). When compiling C++ programs that use C++ streams with gcc on PDO platforms, if you specify the -ObjC++ flag you must also specify the -lstdc++ flag. So, for example, a program "foo" that uses cout (and therefore includes iostream.h ) would be compiled using gcc as follows:
gcc -ObjC++ foo.cc -lstdc++
(69194). On Windows NT, functions that are declared as
__declspec(dllexport)__stdcall
aren't handled properly.
This may affect some Windows header files that you include in your
programs.
(69087). On Windows NT, the compiler sometimes tries to create a
library instead of an executable when a function is declared as
__declspec(dllimport)
(perhaps in a header file), but
the function is actually defined in the file being compiled. The
workaround is to remove the offending
__declspec(dllimport)
.
(69506). On Windows NT, if a function is forward-declared to be
stdcall
but not declared to be stdcall
in
the actual function definition, the compiler will emit code to pop
the arguments off the stack, but won't adjust the function name.
(70212). On Windows NT, if you're building a framework and you
create your own DEF file for it, defining exported objects as
CONSTANT
will produce a warning from the linker advising
you to use the word DATA
instead. If you substitute the
word DATA
for CONSTANT
in your DEF file,
some or all of your objects won't be exported correctly; the linker
will be unable to find them. As a workaround, simply leave the
declarations CONSTANT
and ignore the linker warnings.
(70326). The -static and -dynamic compiler flags are meaningless on Windows NT and shouldn't be used on that platform.
(54831). The PDO compiler cannot apply a user-defined constructor to a global or static C++ object and send an Objective-C message in the same file. To work around this problem, eliminate the constructor, the global, or the Objective-C code.
(38759). The compiler generates wide-character literals for the host endian-ness only. For example, if you are cross-compiling the string L"x" from m68k to i386, it will be a big-endian wide string. The only workaround is not to cross-compile modules that depend on wide characters.
A hard-to-characterize class of bugs are known to cause compiler
crashes. Some of these bugs involve conversions of int
s
to float
s. You can work around at least some of these
bugs by reducing the level of optimization, or by turning off
optimization altogether.